package com.jspx.txweb.dispatcher.handle;

import com.jspx.boot.EnvFactory;
import com.jspx.boot.environment.Environment;
import com.jspx.boot.sign.ErrorRocCode;
import com.jspx.json.JSONException;
import com.jspx.json.JSONObject;
import com.jspx.json.XML;
import com.jspx.security.asymmetric.AsyEncrypt;
import com.jspx.security.asymmetric.impl.RSAEncrypt;
import com.jspx.security.symmetry.Encrypt;
import com.jspx.security.symmetry.impl.DESedeEncrypt;
import com.jspx.security.utils.EncryptUtil;
import com.jspx.txweb.dispatcher.Dispatcher;
import com.jspx.txweb.util.TXWebUtil;
import com.jspx.utils.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * Created by Administrator on 2017/6/18.
 * ROC 加密传输,Rsa加密AES的密码,数据在AES中,密码当然就在RSA中,因为RSA不能加密超过117长度
 */
public class RsaRocHandle extends RocHandle {
    final public static String name = "rsaroc";

    final private static String keyType = "keyType";
    final private static String dataType = "dataType";
    final private static String key = "key";
    final private static String data = "data";

    static public String getSecretDecode(HttpServletRequest request, HttpServletResponse response,JSONObject jsonData) throws Exception {

        String keyTypeT = jsonData.getString(keyType);
        String dataTypeT = jsonData.getString(dataType);
        String keyDataT = jsonData.getString(key);
        String dataT = jsonData.getString(data);
        if (StringUtil.isNULL(keyTypeT) || StringUtil.isNULL(dataTypeT) || StringUtil.isNULL(keyDataT) || StringUtil.isNULL(dataT)) {
            JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "Invalid Request.无效的请求");
            TXWebUtil.print(errorResultJson.toString(4), TXWebUtil.jsonType, response);
            return null;
        }


        String asymmetricAlgorithm = EnvFactory.getEnvironmentTemplate().getString(Environment.asymmetricAlgorithm, RSAEncrypt.class.getName());
        if (!asymmetricAlgorithm.contains(keyTypeT.toUpperCase() + "Encrypt")) {
            JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "Invalid Request.无效的请求,加密算法和后台配置不匹配");
            TXWebUtil.print(errorResultJson.toString(4), TXWebUtil.jsonType, response);
            return null;
        }

        AsyEncrypt asyEncrypt = EnvFactory.getAsymmetricEncrypt();
        byte[] keyData = null;
        if (EncryptUtil.isHex(keyDataT))
            keyData = EncryptUtil.hexToByte(keyDataT);
        else {
            keyData = EncryptUtil.getBase64Decode(keyDataT);
        }
        byte[] passwordByte = asyEncrypt.decryptByPrivateKey(keyData, EncryptUtil.hexToByte(EnvFactory.getPrivateKey()));

        if (ArrayUtil.isEmpty(passwordByte)) {
            JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "Invalid Request.无效的请求,key参数错误1");
            TXWebUtil.print(errorResultJson.toString(4), TXWebUtil.jsonType, response);
            return null;
        }

        String password = new String(passwordByte, Environment.defaultEncode);
        if (!password.contains("-")) {
            JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "Invalid Request.无效的请求,key参数错误2");
            TXWebUtil.print(errorResultJson.toString(4), TXWebUtil.jsonType, response);
            return null;
        }

        String key = StringUtil.substringBefore(password, "-");
        String iv = StringUtil.substringAfter(password, "-");

        if (!ArrayUtil.inArray(new String[]{"aes", "des", "3des", "desede", "xor"}, dataTypeT, true)) {
            JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "Invalid Request.无效的请求,dataType参数错误1");
            TXWebUtil.print(errorResultJson.toString(4), TXWebUtil.jsonType, response);
            return null;
        }

        Encrypt symmetryEncrypt = null;
        if (ArrayUtil.inArray(new String[]{"3des", "desede"}, dataTypeT, true)) {
            symmetryEncrypt = new DESedeEncrypt();
        } else if (ArrayUtil.inArray(new String[]{"aes", "des", "xor"}, dataTypeT, true)) {
            try {
                symmetryEncrypt = (Encrypt) ClassUtil.newInstance("com.jspx.security.symmetry.impl." + dataTypeT.toUpperCase() + "Encrypt");
            } catch (Exception e) {
                JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "Invalid Request.无效的请求,dataType参数错误2");
                TXWebUtil.print(errorResultJson.toString(4), TXWebUtil.jsonType, response);
                return null;
            }
        }

        if (symmetryEncrypt == null) {
            JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "Invalid Request.无效的请求,dataType参数错误3");
            TXWebUtil.print(errorResultJson.toString(4), TXWebUtil.jsonType, response);
            return null;
        }

        symmetryEncrypt.setSecretKey(key);
        symmetryEncrypt.setCipherIv(iv);
        return symmetryEncrypt.getDecode(dataT); //默认16 hex
    }

    @Override
    public void doing(HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        String callStr = getRequestReader( request, response);
        if (StringUtil.isNULL(callStr)) return;

        String rpc = StringUtil.trim(callStr);
        JSONObject jsonData = null;
        if (StringUtil.isXml(rpc)) {
            //XML格式
            try {
                jsonData = XML.toJSONObject(rpc);
            } catch (JSONException e) {
                JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "Invalid Request.无效的请求");
                TXWebUtil.print("<?xml version=\"1.0\" encoding=\"" + Dispatcher.getEncode() + "\"?>\r\n" + XMLUtil.format(XML.toString(errorResultJson, Environment.rocResult)), TXWebUtil.xmlType, response);
            }
        }
        if (StringUtil.isJsonObject(rpc)) {
            //JSON格式
            try {
                jsonData = new JSONObject(rpc);
            } catch (JSONException e) {
                JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "Invalid Request.无效的请求");
                TXWebUtil.print(errorResultJson.toString(4), TXWebUtil.jsonType, response);
                return;
            }
        }

        if (jsonData==null)
        {
            JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "Invalid Request.无效的请求");
            TXWebUtil.print(errorResultJson.toString(4), TXWebUtil.jsonType, response);
            return;
        }
        String secretData =  getSecretDecode( request,  response, jsonData);
        super.callAction(request, response, secretData, true);
    }
}
